package com.ruoyi.system.service.impl

import com.ruoyi.common.annotation.DataSource
import com.ruoyi.common.constant.CacheConstants
import com.ruoyi.common.constant.UserConstants
import com.ruoyi.common.core.redis.RedisCache
import com.ruoyi.common.core.text.Convert.toBool
import com.ruoyi.common.core.text.Convert.toStr
import com.ruoyi.common.enums.DataSourceType
import com.ruoyi.common.exception.ServiceException
import com.ruoyi.common.utils.MyStringUtils
import com.ruoyi.system.domain.SysConfig
import com.ruoyi.system.mapper.SysConfigMapper
import com.ruoyi.system.service.ISysConfigService
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service
import javax.annotation.PostConstruct

/**
 * 参数配置 服务层实现
 *
 * @author ruoyi
 */
@Service
open class SysConfigServiceImpl : ISysConfigService {
    @Autowired
    private lateinit var configMapper: SysConfigMapper

    @Autowired
    private lateinit var redisCache: RedisCache

    /**
     * 项目启动时，初始化参数到缓存
     */
    @PostConstruct
    fun init() {
        loadingConfigCache()
    }

    /**
     * 查询参数配置信息
     *
     * @param configId 参数配置ID
     * @return 参数配置信息
     */
    @DataSource(DataSourceType.MASTER)
    override fun selectConfigById(configId: Long?): SysConfig? {
        val config = SysConfig()
        config.configId = configId
        return configMapper.selectConfig(config)
    }

    /**
     * 根据键名查询参数配置信息
     *
     * @param configKey 参数key
     * @return 参数键值
     */
    override fun selectConfigByKey(configKey: String?): String? {
        val configValue = toStr(redisCache.getCacheObject(getCacheKey(configKey)))
        if (MyStringUtils.isNotEmpty(configValue)) {
            return configValue
        }
        val config = SysConfig()
        config.configKey = configKey
        val retConfig = configMapper.selectConfig(config)
        if (MyStringUtils.isNotNull(retConfig)) {
            redisCache.setCacheObject(getCacheKey(configKey), retConfig?.configValue)
            return retConfig?.configValue
        }
        return org.apache.commons.lang3.StringUtils.EMPTY
    }

    /**
     * 获取验证码开关
     *
     * @return true开启，false关闭
     */
    override fun selectCaptchaEnabled(): Boolean {
        val captchaEnabled = selectConfigByKey("sys.account.captchaEnabled")
        return if (MyStringUtils.isEmpty(captchaEnabled!!)) {
            true
        } else toBool(captchaEnabled)!!
    }

    /**
     * 查询参数配置列表
     *
     * @param config 参数配置信息
     * @return 参数配置集合
     */
    override fun selectConfigList(config: SysConfig?): List<SysConfig> {
        return configMapper.selectConfigList(config)
    }

    /**
     * 新增参数配置
     *
     * @param config 参数配置信息
     * @return 结果
     */
    override fun insertConfig(config: SysConfig): Int {
        val row = configMapper.insertConfig(config)
        if (row > 0) {
            redisCache.setCacheObject(getCacheKey(config.configKey), config.configValue)
        }
        return row
    }

    /**
     * 修改参数配置
     *
     * @param config 参数配置信息
     * @return 结果
     */
    override fun updateConfig(config: SysConfig): Int {
        val temp = configMapper.selectConfigById(config.configId)
        if (temp?.configKey!= config.configKey) {
            redisCache.deleteObject(getCacheKey(temp?.configKey))
        }
        val row = configMapper.updateConfig(config)
        if (row > 0) {
            redisCache.setCacheObject(getCacheKey(config.configKey), config.configValue)
        }
        return row
    }

    /**
     * 批量删除参数信息
     *
     * @param configIds 需要删除的参数ID
     */
    override fun deleteConfigByIds(configIds: Array<Long>) {
        for (configId in configIds) {
            val config = selectConfigById(configId)
            if (UserConstants.YES==config?.configType) {
                throw ServiceException(String.format("内置参数【%1\$s】不能删除 ", config?.configKey))
            }
            configMapper.deleteConfigById(configId)
            redisCache.deleteObject(getCacheKey(config?.configKey))
        }
    }

    /**
     * 加载参数缓存数据
     */
    override fun loadingConfigCache() {
        val configsList = configMapper.selectConfigList(SysConfig())
        for (config in configsList) {
            redisCache.setCacheObject(getCacheKey(config.configKey), config.configValue)
        }
    }

    /**
     * 清空参数缓存数据
     */
    override fun clearConfigCache() {
        val keys = redisCache.keys(CacheConstants.SYS_CONFIG_KEY + "*")
        redisCache.deleteObject(keys)
    }

    /**
     * 重置参数缓存数据
     */
    override fun resetConfigCache() {
        clearConfigCache()
        loadingConfigCache()
    }

    /**
     * 校验参数键名是否唯一
     *
     * @param config 参数配置信息
     * @return 结果
     */
    override fun checkConfigKeyUnique(config: SysConfig): Boolean {
        val configId = if (MyStringUtils.isNull(config.configId)) -1L else config.configId
        val info = configMapper.checkConfigKeyUnique(config.configKey)
        return if (MyStringUtils.isNotNull(info) && info?.configId != configId) {
            UserConstants.NOT_UNIQUE
        } else UserConstants.UNIQUE
    }

    /**
     * 设置cache key
     *
     * @param configKey 参数键
     * @return 缓存键key
     */
    private fun getCacheKey(configKey: String?): String {
        return CacheConstants.SYS_CONFIG_KEY + configKey
    }
}
